use actix_web::{body::BoxBody, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use std::fmt::Debug;

#[derive(Serialize, Deserialize, Debug, ToSchema)]
pub struct ApiResponse<T> {
    pub status: u16,
    pub message: String,
    pub data: T,
}

#[derive(Serialize, Deserialize, Debug, ToSchema)]
pub struct PageRes<T> {
    pub page: u64,
    pub per_page: u64,
    pub total: u64,
    pub list: Vec<T>,
}

impl<T: Serialize + Deserialize<'static> + Debug> ApiResponse<T> {

    pub fn ok(data: T) -> Self {
        ApiResponse {
            status: 200,
            message: "成功".to_string(),
            data,
        }
    }

    pub fn ok_page(page: u64, per_page: u64, total: u64, list: Vec<T>) -> ApiResponse<PageRes<T>> {
        ApiResponse {
            status: 200,
            message: "成功".to_string(),
            data: PageRes {
                page,
                per_page,
                total,
                list,
            },
        }
    }

    pub fn is_ok(&self) -> bool {
        self.status == 200
    }
}

impl<T: Serialize> Responder for ApiResponse<T> {
    type Body = BoxBody;
    fn respond_to(self, _req: &actix_web::HttpRequest) -> HttpResponse {
        HttpResponse::Ok().json(self)
    }
}
